package org.luxor.commons.security.component;

import org.luxor.commons.core.utils.HttpContextUtils;
import org.luxor.commons.core.utils.StrKit;
import org.luxor.commons.core.web.data.R;
import org.luxor.commons.security.entity.AuthenticationSuccessDto;
import org.luxor.commons.security.entity.UserSubject;
import org.luxor.commons.security.utils.TokenUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.util.MimeTypeUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * 身份认证成功处理器
 *
 * @author yanxinming
 */
public class RestAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    private static final Logger logger = LoggerFactory.getLogger(RestAuthenticationSuccessHandler.class);

    private final TokenStore tokenStore;

    public RestAuthenticationSuccessHandler(TokenStore tokenStore) {
        this.tokenStore = tokenStore;
    }


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication userAuthentication) throws IOException, ServletException {
        response.setStatus(HttpStatus.OK.value());
        response.setCharacterEncoding(StrKit.CHARSET_NAME);
        response.setContentType(MimeTypeUtils.APPLICATION_JSON_VALUE);

        UserSubject user = (UserSubject) userAuthentication.getPrincipal();

        logger.debug("当前来源IP:[{}] 登陆成功,账号:[{}] ", HttpContextUtils.getRemoteAddr(request), user.getUsername());

        if (tokenStore != null) {
            String accessToken = TokenUtils.toToken(user.getUsername());
            DefaultOAuth2AccessToken oAuth2AccessToken = new DefaultOAuth2AccessToken(accessToken);
            oAuth2AccessToken.setTokenType(OAuth2AccessToken.BEARER_TYPE.toLowerCase());
            oAuth2AccessToken.setExpiration(new Date(System.currentTimeMillis() + (TokenUtils.ACCESS_TOKEN_VALIDITY_SECONDS * 1000)));
            OAuth2Request oAuth2Request = new OAuth2Request(null, HttpContextUtils.getRemoteAddr(request)
                    , null, true, null, null, null
                    , null, null);
            OAuth2Authentication oauth2Authentication = new OAuth2Authentication(oAuth2Request, userAuthentication);
            tokenStore.storeAccessToken(oAuth2AccessToken, oauth2Authentication);
        }

        String token = "Bearer " + TokenUtils.toToken(user.getUsername());
        long expiresIn = TokenUtils.ACCESS_TOKEN_VALIDITY_SECONDS;
        AuthenticationSuccessDto tokenDto = new AuthenticationSuccessDto(token, expiresIn);
        HttpContextUtils.sendJson(response, new R<>(0, "登陆成功", tokenDto));
    }
}
